package cn.itcast.flink.sink;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.sink.RichSinkFunction;
import org.apache.flink.streaming.api.functions.source.RichSourceFunction;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

/**
 * @author lilulu
 */
//将Flink集合中的数据集DataStream，通过自定义Sink保存到MySQL。
public class StreamSinkMysqlDemo {

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Student {
        private Integer id;
        private String name;
        private Integer age;
    }

    public static class MysqlSink extends RichSinkFunction<Student> {

        private Connection connection = null;
        private PreparedStatement preparedStatement = null;

        @Override
        public void open(Configuration parameters) throws Exception {
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection("jdbc:mysql://node1:3306/?useSSL=false", "root", "123456");
            preparedStatement = connection.prepareStatement("insert into db_flink.t_student(id,name,age) values (?,?,?)");
        }

        public void invoke(Student student, Context context) throws Exception {
            // todo： 数据流中每条数据进行输出操作，调用invoke方法
            preparedStatement.setInt(1, student.id);
            preparedStatement.setString(2, student.name);
            preparedStatement.setInt(3, student.age);
            preparedStatement.execute();
        }

        @Override
        public void close() throws Exception {
            if (preparedStatement != null) {
                preparedStatement.close();
            }
            if (connection != null) {
                connection.close();
            }

        }
    }

    public static void main(String[] args) throws Exception {
        // 1. 执行环境-env
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setParallelism(1);
        // 2. 数据源-source
        DataStreamSource<Student> studentDataStreamSource = env.fromElements(
                new Student(21, "wangwu", 20),
                new Student(22, "zhaoliu", 19),
                new Student(23, "laoda", 25),
                new Student(24, "laoer", 23),
                new Student(25, "laosan", 21)
        );
        // 3. 数据转换-transformation
        // 4. 数据终端-sink
        studentDataStreamSource.addSink(new MysqlSink());
        // 5. 触发执行-execute
        env.execute("StreamSinkMysqlDemo");
    }
}